//
//  BannerView.swift
//  UILbrary
//
//  Created by 斌 on 2017/8/8.
//  Copyright © 2017年 mac. All rights reserved.
//

import UIKit
import SnapKit
import Foundation
import Kingfisher
let cellIdentifier:String = "cellIdentifier"

@objc(BannerViewDelegate)

/// 轮播图代理
public protocol BannerViewDelegate:NSObjectProtocol{
    
    /// 点击banner 图片的代理方法
    ///
    /// - Parameters:
    ///   - atNumeber: 点击了第几个图片
    ///   - bannerView: bannerView
    /// - Returns: nil
    func didSelectItem(atNumeber:Int, bannerView:BannerView)
}


/// 轮播图, 这里会把拥有轮播图的控制器的 `automaticallyAdjustsScrollViewInsets` 属性关掉(有可能会影响到外面的代码, 注意!)
public class BannerView: UIView,UICollectionViewDelegate,UICollectionViewDataSource {
    
    
    /// collectionView
    private var collectionView:UICollectionView?
    /// pageControl
    private var pageControl: UIPageControl?
    /// 计时器
    private var timerEngine:Timer?
    /// 组数 用于循环滚动 banner
    private let maxSections = 3
    /// 代理
    public var bannerViewDlegate:BannerViewDelegate?
    /// 所属控制器, 对控制器做一些配置
    private var viewController:UIViewController?
    
    // 网络图片地址数组
    private var imageUrls:[String]?
    /// 站位 图片数组.
    private var placeHoldImage:UIImage?
    // 标题数组
    private var titleArr:[String]?
    
    //MARK:- init -
    private override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    /// 自定义初始化 轮播图 方法, 传入图片和标题
    /// 因为这里传入了 所属控制器, 外面调用不需要给控制器设置轮播图的代理, 因为在这里面已经设置好了
    /// - Parameters:
    ///   - frame: frame 布局 (建议使用自动布局)
    ///   - viewController: 所属的控制器
    ///   - imageArr: 存 有 image url 地址 的 数组
    ///   - placeHoldImage: 站位图片
    ///   - titleArr: 标题  如果不想展示标题直接传递空就好
    convenience  init(viewController:UIViewController,imageArr:[String],placeHoldImage:UIImage,titleArr:[String]) {
        
        self.init()
        self.bannerViewDlegate = viewController as? BannerViewDelegate
        // 默认是 YES , ScrollView TableView CollectionView 的内容都会向下偏移一段位移
        viewController.automaticallyAdjustsScrollViewInsets = false
        
        self.imageUrls = imageArr
        self.titleArr = titleArr
        self.placeHoldImage = placeHoldImage
        
        // (网络数据请求失败时候) 网络图片数组为空 显示placeHoldImage
        if imageUrls == nil {
            // 这里的 imageUrls 内容只是为了不让数组为空, 具体显示的是 placeHoldImage 图片 跟imageUrls 中的内容无关, 所以 我就随便填了 1,2,3
            // 正式情况下，这里应该填入 默认占位图
            self.imageUrls = ["1","2","3"]
        }else{
            if (imageUrls?.count)! <= 0 {
                self.imageUrls = ["1","2","3"]
            }
        }
        
        initTime()
    }
    
    
    // collocationView
    func initCollectionView(){
        
        /// collectionViewFlowLayout
        let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init()
        layout.minimumLineSpacing = 0
        layout.minimumInteritemSpacing = 0
        layout.sectionInset = UIEdgeInsets.zero
        layout.headerReferenceSize = CGSize.zero
        layout.scrollDirection = .horizontal
        
        
        layout.itemSize = CGSize.init(width: self.bounds.size.width, height: self.bounds.size.height)//self.bounds.size
        /// collectionview
        collectionView = UICollectionView.init(frame: CGRect.zero, collectionViewLayout: layout)
        self.addSubview(collectionView!)
        collectionView?.snp.makeConstraints({ (make) in
            make.top.left.right.bottom.equalTo(0)
        })
        
        
        collectionView?.delegate = self
        collectionView?.dataSource = self
        
        collectionView?.register(BannerVeiwCell.self, forCellWithReuseIdentifier: cellIdentifier as String)
        collectionView?.showsHorizontalScrollIndicator = false
        collectionView?.isPagingEnabled = true
        collectionView?.autoresizesSubviews=false
        // 首先展示 最中间那组的 第0个items
        collectionView?.scrollToItem(at: IndexPath(item:0,section:maxSections / 2), at: .left, animated: false)
        collectionView?.backgroundColor = UIColor.clear
        
        
    }
    
    
    public override func layoutSubviews() {
        super.layoutSubviews()
        // 会被调用
        // 初始化 collectionView
        initCollectionView()
        // 初始化 pageControl
        initPageControl()
        collectionView?.updateConstraints()
        
    }
    
    func initPageControl(){
        pageControl = UIPageControl(frame: CGRect.zero)
        pageControl?.currentPageIndicatorTintColor = UIColor.orange
        pageControl?.pageIndicatorTintColor = UIColor.white
        pageControl?.currentPage = 0
        pageControl?.numberOfPages = (imageUrls?.count)!
        self.addSubview(pageControl!)
        
        pageControl!.snp.makeConstraints { (make) in
            make.left.right.equalTo(0)
            make.bottom.equalTo(-20)
            make.height.equalTo(30)
        }
    }
    
    func initTime(){
        
        collectionView?.reloadData()
        timerEngine = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(nextPage), userInfo: nil, repeats: true)
    }
    
    
    
    // MARK:- collection datasource
    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imageUrls!.count
    }
    
    public func numberOfSections(in collectionView: UICollectionView) -> Int {
        return maxSections
    }
    
    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell:BannerVeiwCell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! BannerVeiwCell
        
        let url = URL(string: (imageUrls?[indexPath.row])!)
        // 加载图片
//        cell.bannerImage?.kf.setImage(with: url, placeholder: self.placeHoldImage, options: [KingfisherOptionsInfoItem.cacheOriginalImage], progressBlock: { (receivedSize, totalSize) in
//            // 图片下载过程
//
//        }, completionHandler: { (image, error, cacheType, url) in
//            // 图片下载完成 回调
//        })
        
        if self.titleArr == nil {
            cell.titleLabel?.isHidden = true
            cell.adjustmentConstraints()
        } else if (self.titleArr?.count)! <= 0{
            cell.titleLabel?.isHidden = true
            cell.adjustmentConstraints()
        } else {
            cell.titleLabel?.text = self.titleArr?[indexPath.row]
        }
        return cell
    }
    
    //MARK: - collectionViewDelegate
    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("点击了第\(indexPath.row) 个图片")
        // 调用代理
        self.bannerViewDlegate?.didSelectItem(atNumeber: indexPath.row, bannerView: self)
    }
    
    //MARK: - scrollView delegate
    public func scrollViewDidScroll(_ scrollView: UIScrollView) {
        // pageControl 当前页面控制
        let page = Int(((collectionView?.contentOffset.x)! + 0.5*(collectionView?.bounds.size.width)!) / self.bounds.size.width)
        let currentPage = page % (imageUrls?.count)!
        pageControl?.currentPage = currentPage
    }
    
    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        collectionView?.scrollToItem(at: IndexPath(item: (pageControl?.currentPage)!, section: 1), at: .left, animated: false)
    }
    
    // 当手动拖动开始时, 结束计时器
    public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        timerEngine?.invalidate()
        timerEngine = nil
    }
    // 当手动拖动结束后 开启计时器
    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        initTime()
    }
    
    //MARK: - selector event 下一页
    @objc private func nextPage(){
        //print("下一页")
        // 获取当前 inexPath
        let currentIndexPath = self.collectionView?.indexPathsForVisibleItems.last!
        // 获取中间组 indexPath (所有的图片都是最中间的那一组 为主)
        let middleIndexPath = IndexPath(item: (currentIndexPath?.item)!, section: 1)
        
        // 直接显示中间那一组
        collectionView?.scrollToItem(at: middleIndexPath, at: .left, animated: false)
        
        // 要动画挪动的下一个 图片
        var nextItem = middleIndexPath.item + 1
        var nextSection = middleIndexPath.section
        if nextItem==imageUrls?.count{
            // 当最后一张图片时, 要回到第一个图片显示. 这里借用了第二组的第一个 item
            nextItem = 0
            nextSection += 1
        }
        let nextIndexPath = IndexPath(item: nextItem, section: nextSection)
        //pageControl?.currentPage = nextItem
        collectionView?.scrollToItem(at: nextIndexPath, at: .left, animated: true)
    }
}

